/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package cz.cvut.fel.taskpro.view.controller;

import cz.cvut.fel.taskpro.business.imanager.IUserBusiness;
import cz.cvut.fel.taskpro.business.support.BusinessRuleException;
import cz.cvut.fel.taskpro.business.support.TaskProException;
import cz.cvut.fel.taskpro.data.entity.Kantor;
import cz.cvut.fel.taskpro.data.entity.Student;
import cz.cvut.fel.taskpro.data.entity.TaskProUser;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.List;
import javax.activation.MimetypesFileTypeMap;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import org.primefaces.event.FileUploadEvent;
import org.primefaces.model.UploadedFile;

/**
 * This controller is responsible for working with users. It provide import
 * users, modify users, remove users and so no. This controller is session scope
 * and it is called as userBean.
 *
 * @author Tom
 * @version 1.0.0. beta
 *
 */
@ManagedBean(name = "userBean")
@SessionScoped
public class UserBean extends AbstractFileController implements Serializable {

    private boolean isImport;
    private boolean isAdd;
    private boolean displayPreview;
    String stateOfUser;
    private TaskProUser newUser;
    private TaskProUser selectedUser;
    private List<TaskProUser> users;
    private List<Kantor> kantors;
    private List<Student> students;
        private UploadedFile img;
    @EJB
    private IUserBusiness userB;
    /**
     * This method initialize class after construction. It is called automaticly 
     * after constructione.
     */
    @PostConstruct
    public void init() {
        newUser = new TaskProUser();
        recognizeLogin();

    }

    public UserBean() {
    }

    /**
     * This method initialize controller to state in which is only possible
     * single manually add user. The view redered param are set up.
     * @return redirection parameter addUserAdmin, which redirect to user
     * on site <code>addUserAdmin.hxtml</code>.
     */
    public String loadBeanToAdd() {
        isImport = false;
        isAdd = true;
        displayPreview = false;
        return "addUserAdmin";
    }

    /**
     * This method initialize controller to state in which is only possible mass
     * import to adding users. The view redered param are set up.
     *
     * @return redirection parameter addUserAdmin, which redirect to user
     * on site <code>addUserAdmin.hxtml</code>.
     */
    public String loadBeanToImport() {
        isImport = true;
        isAdd = false;
        displayPreview = false;
        return "addUserAdmin";
    }

    /**
     * This method ask business layer for add new user, which has selected
     * state. States are admin, kantor, student.
     */
    public void addUser() {
        try {
            userB.addUser(newUser, stateOfUser);
            printSuccMessage("Add user: ", "The user with username: " + newUser.getLogin() + " has been successfully added.");
            newUser = new TaskProUser();
        } catch (BusinessRuleException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        } catch (TaskProException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        }

    }

    /**
     * This method ask business layer for reseting password to selected user.
     */
    public void resetPassword() {
        try {
            userB.resetPassword(selectedUser);

            printSuccMessage("Reset password:", " The password was successfully reseted to student" + selectedUser.getLogin());

        } catch (BusinessRuleException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        } catch (TaskProException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        }
    }

    /**
     * This method ask business layer to modify selected user.
     */
    public void modifyUser() {
        try {
            userB.modifyUser(selectedUser, null);
            printSuccMessage("User modify.", "User: " + selectedUser.getLogin() + " personal identificators has been successfully modificated.");
        } catch (BusinessRuleException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        }
    }

    /**
     * This method ask business layer to remove selected user. Then is user
     * remove from actual loaded user list.
     */
    public void removeUser() {
        try {
            userB.removeUser(selectedUser);
            students.remove(selectedUser);
            printSuccMessage("Removing student: ", "The student " + selectedUser.getName() + " " + selectedUser.getSurname() + " "
                    + "has been successfully removed.");
            selectedUser = null;
        } catch (BusinessRuleException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        }
    }

    /**
     * This method ask business layer for all students in system. Then is made
     * redirection.
     *
     * @return redirection parameter checkStudentsAdmin, which redirect to user
     * on site
     * <code>checkStudentsAdmin.hxtml</code>
     */
    public String loadStudents() {
        students = userB.getStudentsAll();
        return "checkStudentsAdmin";
    }
        /**
     * This method ask business layer for all students who are teached by logged kantor in system. 
     * Then the redirection is made.
     *
     * @return redirection parameter showStudents, which redirect to user
     * on site
     * <code>showStudents.hxtml</code>
     */
    public String loadStudentsByKantor() {
        students = userB.getStudenstByKantor(loggedKantor);
        return "showStudents";
    }
            /**
     * This method ask business layer for all kantors in system. 
     * Then the redirection is made.
     *
     * @return redirection parameter checkKantorsAdmin, which redirect to user
     * on site
     * <code>checkKantorsAdmin.hxtml</code>
     */
    public String loadKantors() {
        kantors = userB.getAllKantor();
        return "checkKantorsAdmin";
    }

    /**
     * This emthod ask business layer for read file with users and then modify 
     * <code> List of users</code> in which are now actually readed user.
     * This method support csv and read file for requied format see:
     * @see IUserBusiness#readCSV(java.io.InputStream) 
     * @see IUserBusiness#readExcel(java.io.File) 
     */
    public void addUserFromFile(FileUploadEvent event) {
        try {
            img = event.getFile();
            InputStream stream;
            stream = event.getFile().getInputstream();
            MimetypesFileTypeMap mimeTypesMap = new MimetypesFileTypeMap();
            File fileWithUsers = inputStreamToFile(stream, event.getFile().getFileName());
            String mimeType = mimeTypesMap.getContentType("neco.csv");
            String mime2 = mimeTypesMap.getContentType("neco.xsl");
            String fileName = fileWithUsers.getName();
            if (fileName.endsWith("csv")) {
                users = userB.readCSV(img.getInputstream());
                displayPreview = true;
                printSuccMessage("Import users: ", "The users from file " + fileName + " was succesfuuly loaded.");
            } else if ((fileName.endsWith("xls")) || (fileName.endsWith("xlsx"))) {
                users = userB.readExcel(fileWithUsers);
                displayPreview = true;
                printSuccMessage("Import users: ", "The users from file " + fileName + " was succesfuuly loaded.");
            } else {
                printErrMessage("File IO", "Incompatible file type.");
            }
        } catch (IOException ex) {
            printErrMessage("File IO", "There was problem during reading file.");
        } catch (BusinessRuleException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        } catch (TaskProException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        }
    }
    /**
     * This method ask business layer for add new list of users.
     */
    public void addUsersFromFile() {
        try {
            userB.addUser(users);
            printSuccMessage("Adding users: ", "All users were successfully added and all notification to users were successfully sended");
        } catch (BusinessRuleException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        } catch (TaskProException ex) {
            printErrMessage(ex.getExceptionCode(), ex.getErrorMessage());
        }
    }
    /**
     * This method remove user from local list.
     * @param user user to remove from list.
     */
    public void removeFromList(TaskProUser user) {
        this.users.remove(user);
        printSuccMessage("Remove user: ", "The user " + user.getName() + " " + user.getSurname() + " has been successfully remove from import list");
    }

    public List<Kantor> getKantors() {
        return kantors;
    }

    public void setKantors(List<Kantor> kantors) {
        this.kantors = kantors;
    }

    public List<Student> getStudents() {
        return students;
    }

    public void setStudents(List<Student> students) {
        this.students = students;
    }

    public TaskProUser getSelectedUser() {
        return selectedUser;
    }

    public void setSelectedUser(TaskProUser selectedUser) {
        this.selectedUser = selectedUser;
    }

    public TaskProUser getNewUser() {
        return newUser;
    }

    public void setNewUser(TaskProUser uzivatel) {
        this.newUser = uzivatel;
    }

    public String getStateOfUser() {
        return stateOfUser;
    }

    public void setStateOfUser(String stateOfUser) {
        this.stateOfUser = stateOfUser;
    }

    public boolean isDisplayPreview() {
        return displayPreview;
    }

    public void setDisplayPreview(boolean displayPreview) {
        this.displayPreview = displayPreview;
    }

    public boolean isIsAdd() {
        return isAdd;
    }

    public void setIsAdd(boolean isAdd) {
        this.isAdd = isAdd;
    }

    public boolean isIsImport() {
        return isImport;
    }

    public void setIsImport(boolean isImport) {
        this.isImport = isImport;
    }

    public List<TaskProUser> getUsers() {
        return users;
    }

    public void setUsers(List<TaskProUser> users) {
        this.users = users;
    }
}
